<template>
    <el-container class="layout-out-content">
        <el-aside class="layout-side-row">
            <div class="layout-side-add-box">
                  <el-button class="add-btn" type="primary" @click="addNewCompany">新增</el-button>
                  <el-button class="refresh-btn" type="primary" :icon="RefreshRight" @click="getCompanyList"></el-button>
            </div>
            <el-scrollbar class="layout-side-scrollbar" v-loading="companyLoading">
                <el-menu :default-active="companyChecked.key">
                    <el-menu-item v-for="e in companyList" :index="e.key" @click="checkCompany(e)" @contextmenu.prevent="onRightClick($event, e)">{{ e.name }}</el-menu-item>
                </el-menu>
            </el-scrollbar>
            <div class="layout-side-upload">
                <div class="upload-per" :style="'width: ' + (uploadFile ? (uploadFile.per || 0) : 0) + '%'"></div>
                <div class="upload-text">{{ uploadedList.length }} / {{ uploadList.length }}</div>
            </div>
        </el-aside>
        <el-container class="layout-right-row">
            <el-header class="layout-header-row">
                <div class="layout-header-box">
                    <div class="company-title" v-if="companyChecked.key">
                        {{companyChecked.name}}
                    </div>
                    <div class="company-title-empty" v-else>
                        请选择企业
                    </div>
                    <div class="company-right-box" v-if="companyChecked.key">
                        <div class="search-box">
                            <el-input
                                v-model="searchKey"
                                style="width: 200px"
                                placeholder="请输入搜索关键词"
                                >
                                <template #append>
                                    <el-button :icon="Search" @click="doSearch"/>
                                </template>
                            </el-input>
                        </div>
                        <div class="tool-box">
                            <el-button class="add-btn" type="primary" :icon="RefreshRight" @click="refreshFileList"></el-button>
                            <el-button class="add-btn" type="primary" @click="addNewFolder">新增文件夹</el-button>
                            <el-button class="add-btn" type="primary" @click="openUpload">上传文件</el-button>
                        </div>
                    </div>
                </div>
            </el-header>
            <el-main class="layout-main-content" v-loading="fileLoading">
                <el-scrollbar v-if="isSearch">
                    <div class="list-out-row" v-if="searchFileList.length > 0">
                        <div class="search-list-out-box">
                            <div class="list-item-row" v-for="e in searchFileList" :key="e.key"  @contextmenu.prevent="showFileMenu(e, $event)" @dblclick="doubleClickFile(e)">
                                <div class="list-icon-box" v-if="e.isDirectory">
                                    <el-icon><Folder /></el-icon>
                                </div>
                                <div class="list-icon-box" v-else>
                                    <el-icon><Document /></el-icon>
                                </div>
                                <div class="item-name" :title="e.name"> {{ e.name }}</div>
                                <div class="item-path" :title="e.parentPath"> {{ e.parentPath }}</div>
                            </div>
                        </div>
                    </div>
                    <div class="list-empty-row" v-else>
                        <el-empty description="暂无文件" />
                    </div>
                </el-scrollbar>


                <el-scrollbar v-else>
                    <div class="list-out-row" v-if="fileList.length > 0 && fileList[fileList.length - 1].length > 0">
                        <div class="list-out-box">
                            <div class="back-item-row" @dblclick="doBackFolder" v-if="fileList.length > 1">
                                <div class="list-icon-box">
                                    <el-icon><Back /></el-icon>
                                </div>
                                <div>返回上一层</div>
                            </div>
                            <div class="list-item-row" v-for="e in fileList[fileList.length - 1]" :key="e.key"  @contextmenu.prevent="showFileMenu(e, $event)" @dblclick="doubleClickFile(e)">
                                <div class="list-icon-box" v-if="e.isDirectory">
                                    <el-icon><Folder /></el-icon>
                                </div>
                                <div class="list-icon-box" v-else>
                                    <el-icon><Document /></el-icon>
                                </div>
                                <div class="item-name"> {{ e.name }}</div>
                            </div>
                        </div>
                    </div>
                    <div class="list-empty-row" v-else>
                        <div class="back-item-row" @dblclick="doBackFolder" v-if="fileList.length > 1">
                            <div class="list-icon-box">
                                <el-icon><Back /></el-icon>
                            </div>
                            <div>返回上一层</div>
                        </div>
                        <el-empty description="暂无文件" />
                    </div>
                </el-scrollbar>
            </el-main>
            
            <el-footer class="layout-main-footer">
                <div class="layout-main-row">
                    <div class="footer-title">
                        当前路径：
                    </div>
                    <div class="footer-value">
                        <el-scrollbar>
                            <span v-if="filePathList.length > 0"> {{filePathList[filePathList.length - 1]}}</span>
                            <span v-else>{{companyPath}}</span>
                        </el-scrollbar>
                    </div>
                </div>
            </el-footer>
        </el-container>
        <CompanyEdit :show="showCompanyEdit" :editData="editData" @close="closeCompanyEdit"/>
        <FileEdit :show="showFileEdit" :editData="editData" @close="closeFileEdit" />
        <UploadFile :show="showUpload" :path="filePathList[filePathList.length - 1]" @close="closeUpload" @doUpload="doUpload" v-if="filePathList.length > 0"/>
        <!-- 企业右击菜单 -->
        <div v-if="showContextMenu" class="custom-context-menu" :style="{ top: contextMenuStyle.y + 'px', left: contextMenuStyle.x + 'px' }" >
            <div class="menu-item" @click="openCompanyEdit(contextMenuData)">编辑</div>
            <div class="menu-item-error" @click="preDelete(contextMenuData)">删除</div>
        </div>
        <div v-if="isContextMenuVisible" class="custom-context-menu" :style="{ top: contextMenuPosition.y + 'px', left: contextMenuPosition.x + 'px' }">
            <div class="menu-item" @click="getFileList(selectedItem.path)" v-if="selectedItem.isDirectory">打开文件夹</div>
            <div class="menu-item" @click="openFile(selectedItem)" v-else>打开文件</div>
            <div class="menu-item" @click="openFileEdit(selectedItem)">重命名</div>
            <div class="menu-item" @click="openFilePath(selectedItem)" v-if="isSearch">打开文件位置</div>
            <div class="menu-item-error" @click="preDeleteFile(selectedItem)">删除</div>
        </div>
    </el-container>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { RefreshRight, Search, Folder, Document, Back } from '@element-plus/icons-vue'
import { generateRandomString } from '../utils/Uitls'
import CompanyEdit  from './components/CompanyEdit.vue'
import FileEdit  from './components/FileEdit.vue'
import UploadFile from './components/UploadFile.vue'
import { ElMessage, ElMessageBox } from 'element-plus'

const companyPath = "E:/file-manager";
const companyList = ref<any[]>()
const companyChecked = ref<any>({})
const companyLoading = ref<boolean>(false)
const showCompanyEdit = ref<boolean>(false)
const showFileEdit = ref<boolean>(false)
const editData = ref<any>({})

const showContextMenu = ref(false)
const contextMenuStyle = ref({ x: 0, y: 0 })
const contextMenuData = ref<any>(null)

const fileList = ref<any[]>([])
const filePathList = ref<string[]>([])
const fileLoading = ref<boolean>(false)

const searchKey = ref<string>("")
const isSearch = ref<boolean>(false)
const searchFileList = ref<any[]>([])

const isContextMenuVisible = ref(false);
const contextMenuPosition = ref({ x: 0, y: 0 });
const selectedItem = ref<any>();

const showUpload = ref<boolean>(false)
const uploadList = ref<any[]>([])
const uploadedList = ref<any[]>([])
const uploadFile = ref<any>()
const isUploading = ref<boolean>(false) 
const processedFiles = new Set<string>()

onMounted(() => {
    getCompanyList()
    document.addEventListener('click', () => {
        showContextMenu.value = false
        isContextMenuVisible.value = false;
    })
})

function onRightClick(event: MouseEvent, row: any) {
  contextMenuStyle.value = {
    y: event.clientY,
    x: event.clientX
  }
  // 2. 存储点击的数据
  contextMenuData.value = row
  // 3. 显示菜单
  showContextMenu.value = true
}

async function getCompanyList() {
    companyLoading.value = true
    const result = await window.electronAPI.readDirectory(companyPath);
    if (result.success) {
        let list = [...result.data]
        let dataList = []
        for (let row of list) {
            if (row.isDirectory) {
                row.key = generateRandomString(24)
                dataList.push(row)
            }
        }
        companyList.value = dataList
        if (dataList.length > 0) {
            checkCompany(dataList[0])
        } else {
            checkCompany({})
        }
    } else {
        companyList.value = []
    }
    companyLoading.value = false
}
function checkCompany(row:any) {
    companyChecked.value = row
    fileList.value = []
    filePathList.value = []
    getFileList(row.path)
}
function addNewCompany() {
    let data = {
        parentPath: companyPath
    }
    openCompanyEdit(data)
}
function openCompanyEdit(row: any) {
    editData.value = row
    showCompanyEdit.value = true
}
function closeCompanyEdit() {
    showCompanyEdit.value = false
    getCompanyList()
}

function addNewFolder() {
    let pathList = [...filePathList.value || []]
    let data = {
        parentPath: pathList[pathList.length - 1]
    }
    openFileEdit(data)
}
function openFileEdit(row: any) {
    editData.value = row
    showFileEdit.value = true
}
function closeFileEdit() {
    editData.value = {}
    showFileEdit.value = false
    refreshFileList()
}
async function openFilePath(row: any) {
    const result = await window.electronAPI.getFolderSteps(companyPath, row.path);
    if (result.success) {
        let pathArr = [...result.data]
        if (pathArr.length > 1) {
            pathArr.splice(-1)
        }
        let list = []
        for (let path of pathArr) {
            let row = await getFileListRow(path)
            list.push(row)
        }
        fileList.value = list
        filePathList.value = pathArr
        isSearch.value = false
    } else {
        ElMessage.error("文件位置获取失败")
    }
}
async function getFileListRow(path: string) {
    const result = await window.electronAPI.readDirectory(path);
    let resultList = []
    if (result.success) {
        const dataList = result.data.map((file:any) => ({
            ...file,
            key: generateRandomString(24)
        }));
        dataList.sort((a:any, b:any) => {
            if (a.isDirectory !== b.isDirectory) {
                return a.isDirectory ? -1 : 1;
            }
            return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
        });
        resultList = dataList
    }
    return resultList;
}
function preDelete(row:any) {
    ElMessageBox.confirm('您确定要删除【' + row.name + "】吗？<br/>确认后该企业下的文件将会被删除", '警告', { confirmButtonText: '确认', cancelButtonText: '取消', dangerouslyUseHTMLString: true, center: true}).then(() => {
      doDelete(row)
    })
}
function preDeleteFile(row:any) {
    let message = "您确定要删除【" + row.name + "】吗？";
    if (row.isDirectory) {
        message +="<br/>确认后该文件夹下的文件将会被删除！"
    }
    ElMessageBox.confirm(message, '警告', { confirmButtonText: '确认', cancelButtonText: '取消', dangerouslyUseHTMLString: true, center: true}).then(() => {
      doDeleteFile(row)
    })
}

async function doDelete(row:any) {
    let path = row.path
    const result = await window.electronAPI.deleteFolder(path);
    if (result.success) {
        ElMessage.success("删除成功")
        getCompanyList()
    } else {
        ElMessage.error("删除失败")
    }
}
async function doDeleteFile(row:any) {
    let path = row.path
    fileLoading.value = true
    const result = await window.electronAPI.deleteFolder(path);
    fileLoading.value = false
    if (result.success) {
        ElMessage.success("删除成功")
        refreshFileList()
    } else {
        ElMessage.error("删除失败")
    }
}
async function getFileList(path: string) {
    fileLoading.value = true
    const result = await window.electronAPI.readDirectory(path);
    if (result.success) {
        const dataList = result.data.map((file:any) => ({
            ...file,
            key: generateRandomString(24)
        }));
        dataList.sort((a:any, b:any) => {
            if (a.isDirectory !== b.isDirectory) {
                return a.isDirectory ? -1 : 1;
            }
            return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
        });
        fileList.value.push(dataList)
    } else {
        fileList.value.push([])
    }
    filePathList.value.push(path)
    fileLoading.value = false
}
async function refreshFileList() {
    let filePath = [...filePathList.value || []]
    if (filePath.length > 0) {
        fileLoading.value = true
        let path = filePath[filePath.length - 1]
        const result = await window.electronAPI.readDirectory(path);
        if (result.success) {
            const dataList = result.data.map((file:any) => ({
                ...file,
                key: generateRandomString(24)
            }));
            dataList.sort((a:any, b:any) => {
                if (a.isDirectory !== b.isDirectory) {
                    return a.isDirectory ? -1 : 1;
                }
                return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
            });
            fileList.value[fileList.value.length - 1] = dataList
        } else {
            fileList.value[fileList.value.length - 1] = []
        }
        fileLoading.value = false
    }
}

function showFileMenu(item:any, event:any) {
  selectedItem.value = item;
  contextMenuPosition.value = {
    x: event.clientX,
    y: event.clientY
  };
  isContextMenuVisible.value = true;
}
async function openFile(row:any) {
    const result = await window.electronAPI.openFileExternal(row.path);
    if (!result.success) {
        ElMessage.error("打开失败")
    }
}
function doubleClickFile(row:any) {
    if (row.isDirectory) {
        getFileList(row.path)
    } else {
        openFile(row)
    }
}

function doBackFolder() {
    let list = [...fileList.value || []]
    let pathList = [...filePathList.value || []]
    if (list.length > 1) {
        list.splice(-1)
        pathList.splice(-1)
        fileList.value = list
        filePathList.value = pathList
    }
}
async function doSearch() {
    fileLoading.value = true
    searchFileList.value = []
    if (searchKey.value) {
        isSearch.value = true
        let filePath = [...filePathList.value || []]
        if (filePath.length > 0) {
            let path = filePath[filePath.length - 1]
            const result = await window.electronAPI.searchInDirectory(path, searchKey.value);
            if (result.success) {
                const dataList = result.data
                .filter((file: any) => !file.isDirectory)
                .map((file:any) => ({
                    ...file,
                    key: generateRandomString(24)
                }));
                searchFileList.value = dataList
            }
        }
    } else {
        isSearch.value = false
    }
    fileLoading.value = false
}
function openUpload(){
    showUpload.value = true
}
function closeUpload(){
    showUpload.value = false
}
function doUpload(file: any) {
    uploadList.value.push(file)
    if (!uploadFile.value) {
        toUpload()
    }
}
async function toUpload() {
    for (const file of uploadList.value) {
        if (file.per >= 100) continue
        uploadFile.value = file
        const reader = file.stream().getReader()
        const { name: fileName, dir: dir, size: totalSize } = file

        if (totalSize === 0) {
            window.electronAPI.sendChunkToMain({
                name: fileName,
                path: dir,
                chunk: new Uint8Array(), // 空
                index: 0,
                isFirst: true,
                isLast: true
            })
            file.per = 100
        } else {
            let isFirstChunk = true
            let chunkIndex = 0
            let uploadedSize = 0
            while (true) {
                const { done, value } = await reader.read()
                if (done) break
                uploadedSize += value.length
                const progress = Math.floor((uploadedSize / totalSize) * 100)
                file.per = progress
                console.log([...uploadList.value])
                uploadFile.value = { ...file }
                window.electronAPI.sendChunkToMain({
                    name: fileName,
                    path: dir,
                    chunk: value,
                    index: chunkIndex++,
                    isFirst: isFirstChunk,
                    isLast: false
                })

                isFirstChunk = false
            }
            window.electronAPI.sendChunkToMain({
                name: fileName,
                path: dir,
                chunk: new Uint8Array(),
                index: chunkIndex,
                isFirst: false,
                isLast: true
            })
            file.per = 100
        }
        uploadedList.value.push(file)
        uploadFile.value = null
        let nowPath = companyPath
        let pathList = [...filePathList.value || []]
        if (pathList.length > 0) {
            nowPath = pathList[pathList.length - 1]
            if (dir === nowPath) {
                refreshFileList()
            }
        }
    }
}

</script>
<style lang="scss" scoped>
.layout-out-content {
    width: 100vw;
    height: 100vh;
    border-top: solid 1px var(--el-menu-border-color);
    .layout-side-row{
        width: 201px;
        border-right: solid 1px var(--el-menu-border-color);
        .layout-side-add-box{
            width: 200px;
            height: 59px;
            display: flex;
            justify-content: center;
            align-items: center;
            border-bottom: solid 1px var(--el-menu-border-color);
            .add-btn{
                width: 120px;
            }
            .refresh-btn{
                width: 30px;
            }
        }
        .layout-side-scrollbar{
            height: calc(100% - 100px);
            .el-menu{
                border: none!important;
            }
        }
        .layout-side-upload{
            width: 200px;
            height: 39px;
            display: flex;
            justify-content: flex-start;
            align-items: center;
            border-top: solid 1px var(--el-menu-border-color);
            position: relative;
            .upload-per{
                height: 100%;
                background: #409eff64;
            }
            .upload-text{
                position: absolute;
                width: 100%;
                height: 100%;
                line-height: 39px;
                top: 0;
                left: 0;
                text-align: center;
            }
        }
    }
    .layout-right-row{
        position: relative;
        .layout-header-row{
            width: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            border-bottom: solid 1px var(--el-menu-border-color);
            .layout-header-box{
                width: 100%;
                display: flex;
                justify-content: space-between;
                align-items: center;
                .company-title{
                    font-size: 16px;
                    font-weight: bold;
                }
                .company-title-empty{
                    color: #AAAAAA;
                    font-size: 16px;
                    font-weight: bold;
                }
                .company-right-box{
                    position: relative;
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    .search-box{
                        width: 200px;
                        margin-right: 10px
                    }
                    .tool-box{
                        position: relative;
                    }
                }
            }
        }
        .layout-main-content{
            padding: 0;
            .list-out-row{
                width: 100%;
                display: flex;
                justify-content: center;
                align-items: center;
                .list-out-box{
                    width: 100%;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    flex-wrap: wrap;
                    .list-item-row{
                        width: 100%;
                        padding: 10px;
                        border-bottom: solid 1px var(--el-menu-border-color);
                        display: flex;
                        justify-content: flex-start;
                        align-items: center;
                        cursor: pointer;
                        .list-icon-box{
                            width: 30px;
                            height: 30px;
                            font-size: 20px;
                            display: flex;
                            justify-content: center;
                            align-items: center;
                        }
                        .item-name{
                            width: calc(100% - 40px);
                            font-size: 16px;
                            white-space: nowrap;
                            overflow: hidden;
                            text-overflow: ellipsis;
                        }
                    }
                    .back-item-row{
                        width: calc(100% - 20px);
                        padding: 10px;
                        border-bottom: solid 1px var(--el-menu-border-color);
                        display: flex;
                        justify-content: flex-start;
                        align-items: center;
                        cursor: pointer;
                        .list-icon-box{
                            width: 30px;
                            height: 30px;
                            font-size: 20px;
                            display: flex;
                            justify-content: center;
                            align-items: center;
                        }
                    }
                }
                .search-list-out-box{
                    width: 100%;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    flex-wrap: wrap;
                    .list-item-row{
                        width: 100%;
                        padding: 10px;
                        border-bottom: solid 1px var(--el-menu-border-color);
                        display: flex;
                        justify-content: flex-start;
                        align-items: center;
                        cursor: pointer;
                        .list-icon-box{
                            width: 30px;
                            height: 30px;
                            font-size: 20px;
                            display: flex;
                            justify-content: center;
                            align-items: center;
                        }
                        .item-name{
                            width: calc(50% - 10px);
                            font-size: 16px;
                            white-space: nowrap;
                            overflow: hidden;
                            text-overflow: ellipsis;
                        }
                        .item-path{
                            width: calc(50% - 30px);
                            font-size: 16px;
                            white-space: nowrap;
                            overflow: hidden;
                            text-overflow: ellipsis;
                        }
                    }
                }


            }
            .list-empty-row{
                width: 100%;
                .back-item-row{
                    width: calc(100% - 20px);
                    padding: 10px;
                    border-bottom: solid 1px var(--el-menu-border-color);
                    display: flex;
                    justify-content: flex-start;
                    align-items: center;
                    cursor: pointer;
                    .list-icon-box{
                        width: 30px;
                        height: 30px;
                        font-size: 20px;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                    }
                }
            }
        }
        .layout-main-footer{
            width: 100%;
            height: 40px;
            display: flex;
            justify-content: flex-start;
            align-items: center;
            border-top: solid 1px var(--el-menu-border-color);
            .layout-main-row{
                width: 100%;
                height: 30px;
                display: flex;
                justify-content: flex-start;
                align-items: center;
                .footer-title {
                    width: 80px;
                    font-size: 14px;
                }
                .footer-value {
                    width: calc(100% - 90px);
                    font-size: 14px;
                }
            }
        }
    }
    .custom-context-menu {
        position: fixed;
        background: #fff;
        border: 1px solid #ccc;
        z-index: 9999;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        width: 120px;
        border-radius: 4px;
        padding: 5px 0;
        font-size: 14px;
        .menu-item {
            padding: 6px 12px;
            cursor: pointer;
            &:hover {
                background-color: #f5f5f5;
            }
        }
        .menu-item-error{
            color: red;
            padding: 6px 12px;
            cursor: pointer;
            &:hover {
            background-color: #f5f5f5;
            }
        }
    }
}
</style>